Hey there.
In this lecture, we're going to continue to learn about how to listen to user input by checking out
the Context Action Service.
This service allows us to bind a function to listen to a particular user input.
For example, when some condition is met, like if they have some tool equipped or during a set time
frame, and once we no longer need to listen to that user input, we can unbind the function to no longer
execute.
This service is incredibly useful for creating games that need to have cross-platform support, and
this is because the Context Action service enables us to listen to multiple different inputs simultaneously,
such as mouse inputs and touch inputs.
A context is a condition where a player can perform an action, such as having a tool equipped, and
the action is that input that is performed by the player in that particular context.
In fact, Roblox developers actually recommend using the context action service over the user input
service in most situations.
This is because using the user input service means we have to explicitly check whether or not our player
is in a particular context when an action or an input is being performed, and that's a lot more work
than just binding actions.
Contextually.
Using the Context Action service here in the Roblox documentation, we can read that the Context Action
Service allows an experience to bind user input to contextual actions or actions that are only enabled
under some condition or period of time.
For example, allowing a player to open a door only while close by.
And here it explains to us exactly what is a context, what is an action, and maybe some justification
or reasons for why we should bind actions contextually and inside of the service.
We have some methods such as a binding an action to a particular input.
So for example, here in this example code it shows us binding an action.
They called it honk horn.
It passes a function that's going to handle when input occurs which is handled right here in this function.
And then also passes a boolean which tells us whether or not we would like to display a button on the
screen for mobile players.
And then we also pass the different inputs that are responsible for this particular context.
So if we actually take a look at the bind action function, the parameters is we need a name for this
action.
We need a function that's going to be listening to any input.
We have a boolean that tells us whether or not we would like to create a touch button on the screen,
and then we also pass a list of the different input types that we can listen to for this particular
action.
So back in studio we're going to get the context action service by using the Get Service function.
And we can get Context Action service.
And inside of here if we refer to our context action service, as you can see we have access to the
bind action function which takes the name of the action, the function whether or not we would like
to create a touch button, and then a tuple or a list of the different kinds of inputs that are going
to be listening for this particular action.
So what I'm going to do actually real quick is I'm going to create a function called on action.
And then this is the function that we're going to be passing to our bind action function.
So for example here I'm just going to call this action example action one.
And then we can go ahead and pass a reference to our function.
So this is going to be on action.
And right here it tells us the different arguments that are going to be passed to our function.
In this case it's going to pass the string or the name of the action.
It's going to pass a user input state enum.
And it's going to be passing an input object.
So inside of my function, what I can define here is the name of the action.
The input state as well as the input object.
And here I can denote these as a string.
I can denote this as an enum dot user input state.
And then I can denote this as an input object, after which we can also define whether or not we would
like to create a GUI button on the screen for mobile players.
For this one, I'm just going to say true.
And then after this, we can pass any type of input that we would like this action to listen to.
So for example I can pass like an enum dot Keycode.
Maybe I want to listen to the p uh button on your keyboard.
So we'll pass P, or maybe I want to listen to a touch on the screen.
So I could do enum dot user input type dot touch, or I can even pass.
Maybe I want to listen to mouse input.
So I could do enum dot user input type dot mouse button one.
Let's just do that.
So now this function is going to be handling or listening to these three different inputs.
And it's going to give us some information such as the state of the input, whether or not the input
has began or it ended, as well as some other additional information stored inside of our input object.
And I can bind multiple different actions.
So I'm going to copy this and paste this one here.
And I'm just going to call this one example action two.
And they're both going to be using the exact same function.
And inside of this function all I'm going to do is I'm going to check if the input state is equal to
the enum.
Let's say the user input state of begin right.
So our input began.
We can print something like input began.
And then I'm just going to pass the action name here.
So this will tell us whether or not this is an example action one or example action two.
And then I can create an else if statement and check to see if the input state is equal to the enum
dot user input state dot end.
For example.
There's some other different user input states in here, but the only ones that you're going to really
want to care about is begin and end.
So if the input has ended, then we can print input ended.
And again we'll just pass the action name here.
We can also get other information stored inside of the input object.
As you remember, inside of our input object, it stores things such as the key code that was pressed.
It stores the input type, the state we can get, the delta or the position, stuff like that.
But I'm not going to worry about that for now.
But instead what we're going to do is we're going to playtest the game.
And since we have two different actions here, both listening to the exact same inputs, what we should
expect is that this print statement should print twice because we're listening to two different actions.
We have two actions binded, so this should print twice when the input begins and then this should print
twice when the input ends.
Okay, so now that we are in our game, if I listen to some inputs such as my mouse, if I click, as
you can see, we get our input began and then we get our input ended.
Or if I hold down the letter P on my keyboard, input began and then input ended.
So as you can see, the event is working or the action we binded to the context action service is working.
But something you'll notice is that only our example, action two, is being printed in the console,
and our example action one is being ignored.
And this is because we forgot to return a value from our function.
So by default, how the context action service works is that if you have an action or multiple actions
binded to the same input, only one of those actions is going to act upon that input unless you specify
otherwise.
And in order to allow multiple different actions to operate on the exact same input at the end of your
function, you have to return an enum.
And this enum is the context action result dot pass.
So by default if you don't return any value, the value of sync is going to be returned.
And this says the input event will stop at that function and no other bound actions under it will be
executed.
However, if we have again multiple different functions binded to the same input, but we would like
all of them to execute, then we need to pass this pass enum.
And as you can see it says if I pull it up, it says the input event is considered to not have been
handled by function to bind and will continue being passed to actions bound to the same input type.
So if we would like both of these actions to print into the console, then we need to pass this enum
here.
And as you can see, if I start clicking both example action one and example action two is being printed
in the console.
Same thing if I do it with the p button on my keyboard.
Very cool, and for us to see the buttons created on a mobile device will have to emulate this on a
mobile device.
So remember we passed true here to create a button on the screen so we can go ahead and emulate this
on a mobile device.
And then we can play.
And as you can see right here we get two buttons.
One of these belongs to our action one and the other one belongs to action two.
So if I press down this button, as you can see, this button belongs to example action two.
And if I release it, there we go.
Input ended.
Same thing for this one.
This one belongs to example action one.
And if I release it input ended.
So very cool.
We have our two buttons associated with those two different actions.
Now we can go ahead and manipulate or customize these buttons, such as changing the position.
If we don't like where they are on the screen, we can go ahead and move them around.
We can go ahead and set text inside of them, change their size, or even add images inside of these
buttons.
So to do that, what we need to do is refer to the context action service.
And there's a function in there to, for example, set the image of a button and all you need to do
is pass the action name where this button is associated with.
And then you would pass the image ID for that button.
If you would like to set the title, then you would call the set title function again.
You would pass the action name, and then the string that would be placed inside of our button.
So if I set the title for, let's say example action one, and I want to set the text inside of the
button to be something like, uh, let's just do example action one.
Now when the button is going to appear on my screen, it's going to have this text inside of it.
If you would like to manipulate the button and whatever way you'd like, and you want to actually get
the button that is displayed on the screen, then the context action service also has a function called
get button, and this allows you to grab that UI element and change any of the properties inside of
that UI element, such as the size, the position, and things like that.
But the Context Action service automatically includes the ability to set the title, set the image,
or even set the position of the button all within the context action service.
So I'm just going to copy this here and we're going to set it for both example action one and example
action two.
And if we go and playtest our game.
As you can see now, our buttons have the text inside of it.
Unfortunately, as you can see, the text is being cut off because our buttons are so small.
But that is not a problem because we can go ahead, go in here and we can, let's say get one of these
buttons.
I'll store it in a variable.
So we'll do context action service get button, and we'll get the button that's associated with example
action one.
And before we manipulate this button actually what I'm going to do is I'm going to show you this button
inside of our G.
So here's our two buttons.
If we go to my player and we go to player Guy, you can see our context action guy right here.
And then the frame that's storing the buttons.
As you can see right here we have our context action button and another context action button.
And inside of them they have the action icon and the action title.
So the buttons themselves are image buttons.
And inside of them they have the actual icon.
And then they have the text label for the icon itself.
So when we use the get button function, it's going to return to us these image buttons.
And because we get these image buttons, that means we can manipulate all different kinds of properties
such as the position, the size we can change background color, all sorts of stuff, whatever we would
like with these different buttons.
So for example, if I would like to make the button bigger, then I can refer to my button here and
I'm going to denote it as an image button.
I can go ahead and set the button dot size equal to.
Let's say uh we're going to create a new Utum two from offset.
Let's say we want to make the button 200 by 200 pixels.
So now our example action one button is going to be much larger than our example action two button.
So if we go ahead and play test our game.
As you can see, our example action one button is now ginormous.
And as you can see, I can click it right here and we get input began and input ended.
For example action one.
Very cool.
So this is how we can use the Context Action service to listen to user input in different situations.
Once we're done with a particular context and we no longer need to listen to these particular inputs
anymore, then we can easily unbind these functions by using the context action service unbind action
function.
And all we need to do is pass the action name.
And once that's done now, we will no longer be listening to whatever input is associated with that
particular action.
The Context Action service allows us to add cross-platform support to our games quickly and efficiently,
and again, it is recommended to be used in most situations over the user input service.
I hope you're learning a lot and I will see you in the next lecture.